package com.my.ph.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class ImagePalaceUtil {

    /**
     * 图片宽度
     */
    private static final Integer PIC_WIDTH = 1920;
    /**
     * 图片高度
     */
    private static final Integer PIC_HEIGHT = 1080;

    /***  思考笔记  可以跳过
     *  2 和 4 的区别  向下偏移量          0.5 LUMP_WIDTH+  0.5 PIC_SPACE
     *  3 和 4 的区别 第一张图向右偏移量   0.5 LUMP_WIDTH + 0.5 PIC_SPACE
     *  5 和 6 的区别 第一张图向右偏移量   0.5 LUMP_WIDTH+ 0.5 PIC_SPACE
     *  6 和 9 的区别 向下偏移量          0.5 LUMP_WIDTH+ 0.5 PIC_SPACE
     *  7 和 9 的区别 第一张图向右偏移量  LUMP_WIDTH+PIC_SPACE
     *  8 和 9 的区别 第一张图向右偏移量  0.5 LUMP_WIDTH+ 0.5 PIC_SPACE
     */

    // 围边使用的灰色
    private static final int[] COLOR_GREY_BGR = new int[]{230, 230, 230};

    /**
     * @param pics 图片列表
     * @param path 存储路径
     * @return 成功 OR 失败
     */
    public static String palace(List<String> pics, String path) {
        List<BufferedImage> bufferedImages = new ArrayList<>();

        // BufferedImage.TYPE_INT_RGB可以自己定义可查看API
        BufferedImage outImage = new BufferedImage(PIC_WIDTH, PIC_HEIGHT, BufferedImage.TYPE_INT_RGB);

        Graphics2D gra = outImage.createGraphics();
        //设置背景为蓝灰色
        gra.setColor(toColor());
        //填满图片
        gra.fillRect(0, 0, PIC_WIDTH, PIC_HEIGHT);

        // 开始拼凑 根据图片的数量判断该生成哪种样式组合头像

        int size = pics.size();//图片数量
        int sqrt = (int) Math.ceil(Math.sqrt(size));//宽度  一行几张图片
        double LUMP_WIDTH = (double) PIC_WIDTH / sqrt;
        double LUMP_HEIGHT = (double) PIC_HEIGHT / sqrt;

        // 压缩图片所有的图片生成尺寸同意的 为 125*125
        for (String pic : pics) {
            BufferedImage resize2 = resize2(pic, (int) LUMP_WIDTH, (int) LUMP_WIDTH, false);
            bufferedImages.add(resize2);
        }

        for (int i = 0; i < bufferedImages.size(); i++) {
            gra.drawImage(bufferedImages.get(i), (int)((i % sqrt) * LUMP_WIDTH),
                    (int) (((double) i / sqrt) * LUMP_HEIGHT), null);
        }

        File file = path == null ? FileUtil.createTempFile(".png", true) : new File(path + File.separator + StrUtil.uuid() + ".png");
        //文件如果存在先删除，再创建
        try {
            if (!file.getParentFile().exists()) {
                if (!file.getParentFile().mkdirs() && file.exists()) {
                    if (!file.delete() && !file.createNewFile()) {
                        System.out.println("创建失败！");
                    }
                }
            }
        } catch (IOException e) {
            log.error("{}", e.getMessage(), e);
        }

        //将图片写到文件
        try {
            ImageIO.write(outImage, "png", file);
            return file.getPath();
        } catch (IOException e) {
            return null;
        }
    }


    /**
     * 图片缩放
     *
     * @param picPath 本地或网络图片路径
     * @param height  缩放后高度
     * @param width   缩放后宽度
     * @param fill    是否填充灰色
     * @return BufferedImage
     */
    public static BufferedImage resize2(String picPath, Integer height, Integer width, boolean fill) {
        try {
            BufferedImage imageBuff;
            if (picPath.indexOf("https://") == 0 || picPath.indexOf("http://") == 0) { //简单判断是网络图片还是本地图片
                imageBuff = ImageIO.read(new URL(picPath));
            } else {
                imageBuff = ImageIO.read(new File(picPath));
            }

            Image itemp = imageBuff.getScaledInstance(width, height, Image.SCALE_SMOOTH);

            double ratio; // 缩放比例
            // 计算比例
            if ((imageBuff.getHeight() > height) || (imageBuff.getWidth() > width)) {
                if (imageBuff.getHeight() > imageBuff.getWidth()) {
                    ratio = height.doubleValue() / imageBuff.getHeight();
                } else {
                    ratio = width.doubleValue() / imageBuff.getWidth();
                }
                AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);

                itemp = op.filter(imageBuff, null);
            }

            if (fill) {
                BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

                Graphics2D g = image.createGraphics();

                g.setColor(toColor());

                g.fillRect(0, 0, width, height);

                if (width == itemp.getWidth(null))
                    g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), Color.white, null);
                else
                    g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), Color.white, null);
                g.dispose();
                itemp = image;
            }
            return (BufferedImage) itemp;
        } catch (IOException e) {
            log.error("{}", e.getMessage(), e);
        }
        return null;
    }

    /**
     * &#064;toColor  颜色索引转为颜色
     *
     * @return 颜色
     */
    private static Color toColor() {
        return new Color(ImagePalaceUtil.COLOR_GREY_BGR[0], ImagePalaceUtil.COLOR_GREY_BGR[1], ImagePalaceUtil.COLOR_GREY_BGR[2]);
    }

}
